#pragma once
//这个目录建立的意义就是看能不能靠自己写完一个完整的线程池，从线程的包装到最后线程池的包装，加油
#include<iostream>
#include<string>
#include<cstring>
#include<unistd.h>
#include<pthread.h>
#include<vector>
#include<functional>

namespace ThreadModule
{
    static uint32_t number = 1; //为了写线程的名字，一个一个的写
    class Thread
    {
        using func_t = std :: function<void()>;
        static void* Routine(void* args)
        {
            Thread* ref = static_cast<Thread*>(args);
            ref -> EnableRunning();
            if(ref ->_isdeatch)
            {
                ref ->Deatch();
            }
            pthread_setname_np(ref ->_tid,ref ->_name.c_str());  //设置线程的名称
            ref->_func(); //调用自己的回调函数
            return nullptr;
        }

        void EnableDeatch()
        {
            _isdeatch = true;
        }

        void EnableRunning()
        {
            _isrunning = true;
        }
    public:
        Thread(func_t func)
        :_func(func),
        _tid(0),
        _isdeatch(false),
        _isrunning(false)
        {
            _name = "thread-" + std :: to_string(number);
        }
        bool Start()
        {
            if(_isrunning)
            return false; //如果正在运行，咱就不要二次创建了
            _isrunning = true;
            int n = pthread_create(&_tid,nullptr,Routine,(void*)this);
            if(n > 0)
            {
                std :: cerr << "糟糕，线程创建失败了" << std :: endl;
                return false;
            }
            else if(n == 0)
            {
                std :: cout << "线程创建成功" << std :: endl;
            }
            return true;
        }

        bool Deatch()  //把线程进行分离的，让他不用在被等待
        {
            if(_isdeatch)  //如果已经分离，那么不用重复分离
            {
                return false;
            }
            if(_isrunning)
            {
                pthread_detach(_tid);
            }
            EnableDeatch();
            return true;
        }

        bool Stop()  //把线程停下来
        {
            if(_isrunning)  //想要暂停的前提条件就是让线程先动起来
            {
                int n = pthread_cancel(_tid);
                if(n != 0)
                {
                    std :: cerr << "pthread_cancel false" << std :: endl;
                    return false;
                }
                else
                {
                    std :: cout << "线程暂停成功啦" << "，它的名字是：" << _name << std :: endl;
                    return true;
                }
                return false;
            }
        }
        


        void Join()
        {
            if(_isdeatch) return; //它都分离了就不需要等待了
            int n = pthread_join(_tid,&res);
            if(n > 0)
            {
                std :: cout << "线程等待失败！" << std :: endl;
                return;
            }
            else
            {
                std :: cout << "线程等待成功！" << std :: endl;
            }
        }

        std :: string GetName()
        {
            return _name;
        }



    private:
        pthread_t _tid; //线程的tid
        std :: string _name; //保存的是线程的名字
        bool _isdeatch; //线程是否是分离状态
        bool _isrunning; //线程是否是在运行的状态
        void* res; //线程退出时的退出码，这个可以是空的   
        func_t _func; //这个是任务类型
    };
}